from qturboframe.lib.utils.by import By
from qturboframe.lib.webdriver.exceptions import SeleniumError
from qturboframe.lib.report.log import logger

from selenium.webdriver import ActionChains

from qturboframe.public_ui.base_element import BaseElement
from .select_table import SelectTable
from BladeFerm.hui_app.hui_lib.table import Table as HuiTable
from .page import Page

from .base_table import BaseTable
import time

from BladeFerm.hui12_common.function import display_wait


class Table(HuiTable):
    '''
    表格右侧的按钮操作进行封装
    '''
    
    def sidebar_btn(self, table_dict, title_name, operate_name):
        '''
        获取表格侧边栏按钮对象

        :Args:
         - table_dict: 列名和列名信息，字典类型，例：{列名1:列名信息1,列名2:列名信息2}
         - title_name: 查找的单元格列名
         - operate_name: 侧边栏按钮的名称

        :Returns:
            返回表格侧边栏按钮对象
        '''
        # 获取对应单元格对象
        cell = self.get_cell(table_dict, title_name)
        if operate_name in ['权限复制', '绑定三方用户']:
            hidden_btn = cell.find_element_by_attribute('css selector', 'div.h-dropdown-rel span', 'text:...', timeout=0.1)
            hidden_btn.click()
            operate_btn = self._driver.find_element_by_attribute('css selector', 'div.h-select-dropdown ul.h-dropdown-menu li[title={}]'.format(operate_name), 'text:{}'.format(operate_name), timeout=self.timeout)
            ActionChains(self._driver).move_to_element(operate_btn)
            logger.debug('数据进行的操作: {}'.format(operate_name))
        else:
            operate_btn = cell.exist('css selector', 'span[style="display: initial;"]', 'text:{}'.format(operate_name), timeout=0.1)
            if not operate_btn:
                operate_btn = cell.find_element_by_attribute('css selector', 'span', 'text:{}'.format(operate_name), timeout=self.timeout)
            logger.debug('数据进行的操作: {}'.format(operate_name))
        return operate_btn
        
    def page(self, idname=None, father=None):
        '''
        获取hui表格分页栏对象
        重写说明：操作员中心Page类的xpth定位和hui标准定位的xpth不同

        :Args:
         - idname: 分页栏的定位条件，字典类型：{'元素查找方式':'元素查找语句', '辅助属性':'辅助属性值'}
         - father: 分页栏的祖先级元素，可以给分页栏查找限定范围，这样就不需要在整个页面中查找

        :Example:
         - 例: table.page({'xpath':'./following-sibling::ul[@class="h-page"]'})
        '''
        if father is None:
            father = self.element
        if idname:
            self._page = Page(idname, father, 1)
        else:
            self._page = Page(
                {'xpath':'./parent::div[@class="h-table-box"]/following-sibling::div[@class="h-table-pageView"]/ul[contains(@class, "h-page")]'}, father, 1)
        return self._page

    def fixed(self, idname=None, father=None):
        '''
        获取表格固定栏
        重写说明：操作员中心fixed的class名为h-table-fixed-right，标准的为h-table-fixed

        :Args:
         - idname: 固定栏的定位条件，字典类型：{'元素查找方式':'元素查找语句', '辅助属性':'辅助属性值'}
         - father: 固定栏的祖先级元素，可以给固定栏查找限定范围，默认为表格元素

        :Returns:
            返回固定栏对象，固定栏不存在则返回None

        :Example:
         - 例: table.fixed({'xpath':'./div/div[@class="h-table-fixed-right"]'})
        '''
        if father is None:
            father = self.element
        if idname:
            try:
                self._fixed_div = BaseElement(idname, father, timeout=1).element
            except SeleniumError:
                self._fixed_div = None
        else:
            self._fixed_div = father.exist('xpath', './div/div[@class=\'h-table-fixed-right\']', timeout=1)
        return self._fixed_div

    def check_cells_exist(self, table_dict, turn_page=False):
        '''
        检查单元格是否存在
        重新说明：增加了多列单项的表格校验（例：{'列1': 'xx', '列2': 'xx'}）

        :Args:
         - table_dict: 一组单元格列名和单元格内容，字典类型，例：{列名1:'内容1,内容2'}
         - turn_page: 是否自动翻页，默认关闭自动翻页查找功能

        :Example:
         - 例: table.check_cells_exist({'姓名':'admin, manager'}, True)
        '''
        # 表格数据检查
        key_list = list(table_dict.keys())
        for key in key_list:
            if table_dict.get(key) == '-':
                table_dict.pop(key)
        if not table_dict:
            raise AttributeError('表格检查条件为空！')
        if turn_page:
            if self._page.exist():
                self._page.to_first()
        # 查看是否存在冻结列
        fixed_title_list = list()
        if self._fixed_div:
            # 获取冻结列列名列表
            fixed_head_table = BaseTable(
                {'css selector': 'div.h-table-fixed-header>table'}, self._fixed_div, self.timeout)
            fixed_title_list = fixed_head_table.get_title_list()
            logger.debug('表格冻结列显示列名：' + str(fixed_title_list))
        # 获取列名列表
        head_table = BaseTable(
            {'xpath': './div/div[@class=\'h-table-header\']/table'}, self._element, self.timeout)
        title_list = head_table.get_title_list()
        logger.debug('表格显示列名：' + str(title_list))
        # 查找单元格
        value_list = len(list(table_dict.values())[0].split(','))
        key_list = len(list(table_dict.keys()))
        if key_list > 1:
            row_list = self.__get_row_indexes(fixed_title_list, title_list, table_dict, turn_page)
            if len(set(row_list)) == value_list:
                logger.info('单元格存在，检查通过')
            else:
                raise SeleniumError('有单元格不存在，检查不通过，请检查数据后重试！')
        else:
            search_value_list = table_dict.get(list(table_dict.keys())[0]).split(',')
            for value in search_value_list:
                search_dict = {list(table_dict.keys())[0]:value}
                row = self._get_row_index(fixed_title_list, title_list, search_dict, turn_page)
                if row:
                    logger.info('列名为{}，内容为{}的单元格存在，检查通过！'.format(
                        list(table_dict.keys())[0], value))
                else:
                    raise SeleniumError('列名为{}，内容为{}的单元格不存在，检查不通过！'.format(
                        list(table_dict.keys())[0], value))

    def check_rows_reload_finish(self, timeout=10):
        '''
        判定表格行数是否加载完成
        :return:
        '''
        return display_wait(idname={By.CSS_SELECTOR: 'tr.h-table-row'}, flag=0, timeout=timeout, driver=self.element)

    def nocheckbox_select_rows(self, table_dict, title_name, turn_page=False):
        '''
        表格单元格点击选中(针对一些不带checkbox勾选的数据行)

        :Args:
         - table_dict: 一组单元格列名和单元格内容，字典类型，例：{列名1:'内容1,内容2'}
         - title_name: 表格所要勾选的列名
         - turn_page: 是否自动翻页，默认关闭自动翻页查找功能

        :Example:
         - 例: table.nocheckbox_select_rows({'姓名':'admin, manager'}, 列名,True)
        '''
        table_data = self.get_cell(table_dict, title_name)
        if table_data:
            # 进行表格勾选
            table_data.click()
            # hui点击触发时间有延迟
            time.sleep(0.5)


    def click_cell(self, table_dict, title_name, turn_page=False):
        '''
        点击单元格

        :Args:
         - table_dict: 一组单元格列名和单元格内容，字典类型，例：{列名1:'内容1,内容2'}
         - title_name: 表格所要勾选的列名
         - turn_page: 是否自动翻页，默认关闭自动翻页查找功能

        :Example:
         - 例: table.nocheckbox_select_rows({'姓名':'admin, manager'}, 列名,True)
        '''
        table_data = self.get_cell(table_dict, title_name)
        if table_data:
            # 进行表格勾选
            table_data.click()
            # hui点击触发时间有延迟
            time.sleep(0.5)

    def click_table_cell(self, table_dict: dict, click_name, turn_page=False):
        '''click_name
        根据单元格列名和单元格内容查找hui表格中所在的单元格
        2022年新增，为了支持资讯云产品的表格不为按钮的情况
        :Args:
         - table_dict: 列名和内容，字典类型，例：{列名1:内容1,列名2:内容2}
         - click_name: 点击的按钮名称（链接名称）
         - turn_page: 是否自动翻页，默认关闭自动翻页查找功能

        :Returns:
            返回查找的单元格

        :Example:
         - 例: cell = table.get_cell({'姓名':'admin', '年龄':'25'}, '工号', True)
        '''
        #使用滚动既可以找到滚动条以下的数据（虽然页面没有反应，但确实能找到）
        td=self.get_cell(table_dict,"操作",turn_page)
        self._driver.execute_script("arguments[0].scrollIntoView(false);", td)
        td.find_element_by_link_text(click_name).click()


    def set_select_table(self,title_name,row,value):
        '''
        对任务管理新增 专门封装的函数，用于处理 比对咨讯源和比对数据表的逻辑

         :Args:
         - title_name: 列名
         - row: 单元格所在的行数
         - value 设置select_table的值
        '''
        #选择对比表 每个单元格转换成 SelectTable 类型 ，由于没有靠谱的主键 用行数定位
        cell=self.get_cell_by_row_index(title_name,row)
        select_table = SelectTable(cell)
        select_table.set_value_for_single_until_load(value)
		
    def wait(self,time_out=30):
        '''
       资讯云数据专用，等待到table数据加载完毕用于处理数据过多而导致的数据无法加载的情况
        :Args:
        - 超时时间time_out 最大等待时间
       '''
        begin=int(time.time())
        now=begin
        while (begin-now)<time_out:
            load=self.element.exist(By.CSS_SELECTOR,"div.h-spin-main")
            if load == None:
                break
            logger.info(load.text)
            time.sleep(1)
            now=int(time.time())
        else:
            logger.error("超时")